use crate::prelude::download_image;
use base64::Engine;
use log::debug;
use log::info;
use rayon::prelude::*;
use regex::Regex;
use serde_json::{self, Value};
use std::fs;
use std::fs::create_dir_all;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use tokio::runtime;

#[derive(Debug)]
pub struct Resp {
    pub response: String,
    pub cost_time: u64,
}

pub fn create_directory<P: AsRef<Path>>(path: P) -> std::io::Result<()> {
    let path_ref: &Path = path.as_ref();
    if !path_ref.exists() {
        create_dir_all(path_ref)
    } else {
        Ok(())
    }
}
pub trait Summary {
    fn summarize(&self) -> String;
}
pub struct LLMPostProcessor {
    pub resp: String,
}

pub struct LLMStreamPostProcessor {
    pub resp: String,
}
impl Summary for LLMPostProcessor {
    fn summarize(&self) -> String {
        let m: Value = serde_json::from_str(&self.resp).unwrap();
        if let Some(finished) = m.get("done").expect("无法正确获取到数据").as_bool() {
            if finished {
                let cost_time = m.get("eval_duration").expect("获取整体耗时失败!").as_u64();
                m.get("message")
                    .unwrap()
                    .get("content")
                    .expect("获取content失败")
                    .to_string()
            } else {
                "".to_string()
            }
        } else {
            "".to_string()
        }
    }
}
pub fn result_process(resp: String) -> Resp {
    let out = LLMPostProcessor { resp: resp }.summarize();
    // let m: Value = serde_json::from_str(&resp).unwrap();
    // debug!("mesg = {}", resp);
    // let out = m
    //     .get("response")
    //     .and_then(|x| x.as_str())
    //     .unwrap()
    //     .to_string();
    // println!("message = {:?}", resp);
    // let data = if resp.ends_with("\n"){
    //     data = resp
    //     .strip_suffix("\n")
    //     .expect("删除最后的换行符")
    //     .split("\n")
    //     .collect();
    // }
    // let datas: Vec<_> = resp
    //     .strip_suffix("\n")
    //     .expect("删除最后的换行符")
    //     .split("\n")
    //     .collect();
    // let mut out = String::new();
    // let mut cost_time: u64 = 0;
    // for d in &datas {
    //     let m: Value = serde_json::from_str(&d).unwrap();
    //     if let Some(f) = m.get("done").and_then(|x| x.as_bool()) {
    //         if f {
    //             info!("finished = {:?}", &m);
    //             cost_time = m.get("total_duration").and_then(|x| x.as_u64()).unwrap();
    //         }
    //     }
    //     out += &m["message"]["content"].as_str().expect("解析");
    // }
    // let value: Value = serde_json::from_str(datas.last().unwrap()).unwrap();
    // info!("last line = {:?}", value);

    let cost_time = 0u64;
    Resp {
        response: out,
        cost_time: cost_time,
    }
}

pub fn data_to_base64(filename: impl AsRef<Path>) -> String {
    let mut file = fs::File::open(filename).unwrap();
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer).unwrap();
    base64::engine::general_purpose::STANDARD.encode(buffer)
}

pub fn datas_to_base64s<T>(filenames: Vec<T>) -> Vec<String>
where
    T: AsRef<Path> + Sync,
{
    filenames
        .par_iter()
        .map(|x| data_to_base64(x))
        .collect::<Vec<String>>()
}

pub fn b64_to_data<T>(b64: T) -> Vec<u8>
where
    T: AsRef<str> + std::convert::AsRef<[u8]>,
{
    base64::engine::general_purpose::STANDARD
        .decode(b64)
        .unwrap()
}
pub fn is_base64<T>(b64: T) -> bool
where
    T: AsRef<str> + std::convert::AsRef<[u8]>,
{
    match base64::engine::general_purpose::STANDARD.decode(b64) {
        Ok(_) => true,
        _ => false,
    }
}
pub fn b64s_to_datas<T>(b64_vectors: Vec<T>) -> Vec<Vec<u8>>
where
    T: AsRef<str> + Sync + std::convert::AsRef<[u8]>,
{
    let decoded_vectors: Vec<Vec<u8>> = b64_vectors
        .par_iter() // 使用Rayon的并行迭代器
        .map(|b64_str| b64_to_data(b64_str))
        .collect(); // 收集所有解码后的向量

    decoded_vectors
}
pub fn is_image_url(url: &str) -> bool {
    // 定义 URL 的正则表达式
    let url_regex = Regex::new(r"^(http://|https://)?([a-zA-Z0-9.-]+)(:[0-9]+)?(/.*)?$").unwrap();

    // 定义支持的图像扩展名
    let image_extensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp"];

    // 检查 URL 是否匹配正则表达式
    if !url_regex.is_match(url) {
        return false;
    }

    // 检查 URL 是否以支持的图像扩展名结尾
    for ext in &image_extensions {
        if url.to_lowercase().ends_with(ext) {
            return true;
        }
    }

    false
}

pub fn source_to_image(source: &str, filename: &str) -> Vec<u8> {
    let cache_path = "/tmp/cache";
    create_directory(cache_path).expect("创建失败");
    let mut data = Vec::new();
    if is_base64(source) {
        data = b64_to_data(source);
    } else {
        let cache_home = Path::new(cache_path);
        let image_filename = cache_home.join(Path::new(&source.to_string()).file_name().unwrap());
        if !image_filename.exists() {
            let runtime = runtime::Runtime::new().unwrap();
            let download_image = download_image(&*source);
            data = runtime.block_on(download_image).unwrap();
            let mut handle = std::fs::File::create(image_filename).expect("文件不存在");
            let _ = handle.write_all(&data);
        } else {
            let mut handle = std::fs::File::open(image_filename).unwrap();
            handle.read_to_end(&mut data).expect("读取文件失败");
        }
    }
    data
}
